#include "common.h"
#include "mmap_file.h"
#include "mmap_file_op.h"
#include "index_handle.h"
#include <sstream>

using namespace std;
using namespace zsyuung_fs;

const static largefile::MMapOption mmap_option = 
{
    1024000,
    4096,
    4096
};

const static uint32_t main_blocksize = 1024 * 1024 * 64;
const static uint32_t bucket_size = 1000;

static int32_t block_id = 1;

static int debug1 = 1;

int main(int argc, char* argv[])
{
    string mainblock_path;
    string index_path;
    int32_t ret = largefile::TFS_SUCCESS;

    cout << "Input blockid:" << endl;
    cin >> block_id;

    if(block_id < 1)
    {
        cerr << "invalid blockid" << endl;
        exit(-1);
    }

    largefile::IndexHandle* index_handle = new largefile::IndexHandle(".", block_id);

    if(debug1)
    {
        printf("load index...\n");
    }

    ret = index_handle->load(block_id, bucket_size, mmap_option);

    if(ret != largefile::TFS_SUCCESS)
    {
        fprintf(stderr, "load index failed, desc:%s\n", strerror(errno));
        delete index_handle;
        exit(-2);
    }

    stringstream tmp_stream;
    tmp_stream << "." << largefile::MAINBLOCK_DIR_PREFIX << block_id;
    tmp_stream >> mainblock_path;
    
    largefile::FileOperation* mainblock = new largefile::FileOperation(mainblock_path, O_CREAT | O_RDWR | O_LARGEFILE);

    char buffer[4096];
    memset(buffer, '6', sizeof(buffer));

    int32_t data_offset = index_handle->get_block_data_offset();
    uint32_t file_no = index_handle->block_info()->seq_no_;

    if((ret = mainblock->pwrite_file(buffer, sizeof(buffer), data_offset)) != largefile::TFS_SUCCESS)
    {
        fprintf(stderr, "write to main block failed, ret:%d, desc:%s\n", ret, strerror(errno));
        mainblock->close_file();
        delete mainblock;
        delete index_handle;
        exit(-4);
    }

    largefile::MetaInfo meta;
    meta.set_file_id(file_no);
    meta.set_offset(data_offset);
    meta.set_size(sizeof(buffer));
    
    ret = index_handle->write_segment_meta(meta.get_key(), meta);
    if(ret == largefile::TFS_SUCCESS)
    {
        index_handle->commit_block_data_offset(sizeof(buffer));
        index_handle->update_block_info(largefile::C_OPER_INSERT, sizeof(buffer));  
        
        ret = index_handle->flush();
        if(ret != largefile::TFS_SUCCESS)
        {
            fprintf(stderr, "index_handle flush failed, desc:%s\n", strerror(errno));
        }
   }
    else
    {
        fprintf(stderr, "write_segment_meta failed, desc:%s\n", strerror(errno));
    }

    if(ret != largefile::TFS_SUCCESS)
    {
        fprintf(stderr, "write to mainblock failed\n");
    }
    else
    {
        printf("write successfully, block_id:%d, file_no:%d\n", file_no, block_id);
    }

    mainblock->close_file();

    delete mainblock;
    delete index_handle;
    return 0;
}
